package com.tanhua.server.service;

import cn.hutool.core.collection.CollUtil;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.MovementApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.Movement;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.MovementsVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.dubbo.config.annotation.DubboReference;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class MovementService {

    @Autowired
    private OssTemplate ossTemplate;

    @DubboReference
    private MovementApi movementApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 发布动态
     */
    public void publishMovement(Movement movement, MultipartFile[] imageContent) throws IOException {
        //1、判断发布动态的内容是否存在
        if (StringUtils.isEmpty(movement.getTextContent())) {
            throw new BusinessException(ErrorResult.contentError());
        }
        //2、获取当前登录的用户id
        Long userId = UserHolder.getUserId();
        //3、将文件内容上传到阿里云OSS，获取请求地址
        List<String> medias = new ArrayList<>();
        for (MultipartFile multipartFile : imageContent) {
            String upload = ossTemplate.upload(multipartFile.getOriginalFilename(), multipartFile.getInputStream());
            medias.add(upload);
        }
        //4、将数据封装到Movement对象
        movement.setUserId(userId);
        movement.setMedias(medias);
        //5、调用API完成发布动态
        movementApi.publish(movement);
    }

    //查询个人动态
    public PageResult findByUserId(Long userId, Integer page, Integer pagesize) {
        //1、根据用户id，调用API查询个人动态内容（PageResult  -- Movement）
        PageResult pr = movementApi.findByUserId(userId, page, pagesize);
        //2、获取PageResult中的item列表对象
        List<Movement> items = (List<Movement>) pr.getItems();
        //3、非空判断
        if (items == null) {
            return pr;
        }
        //3.5查询redis点赞、喜欢、评论数
        this.count(items);
        //4、循环数据列表
        UserInfo userInfo = userInfoApi.findById(userId);
        List<MovementsVo> vos = new ArrayList<>();
        for (Movement item : items) {
            //5、一个Movement构建一个Vo对象
            MovementsVo vo = MovementsVo.init(userInfo, item);
            //查询hasLiked、hasLoved
            Object o = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LIKE_" + userId);
            if (o==null){
                vo.setHasLiked(0);
            }else {
                vo.setHasLiked(1);
            }
            Object o1 = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LOVE_" + userId);
            if (o1==null){
                vo.setHasLoved(0);
            }else {
                vo.setHasLoved(1);
            }
            vos.add(vo);
        }
        //6、构建返回值
        pr.setItems(vos);
        return pr;
    }
    //查询redis点赞、喜欢、评论数
    private void count(List<Movement> items) {

        for (Movement item : items) {
            ObjectId id = item.getId();
            String likeCount = (String) redisTemplate.opsForHash().get("COMMENT_" + id.toHexString(), "LIKE_COUNT");
            Integer like;
            if (likeCount==null){
                like= 0;
            }else {
                like = Integer.valueOf(likeCount);
            }
            item.setLikeCount(like);

            String loveCount = (String) redisTemplate.opsForHash().get("COMMENT_" + id.toHexString(), "LOVE_COUNT");
            Integer love;
            if (loveCount==null){
                love= 0;
            }else {
                love = Integer.valueOf(loveCount);
            }
            item.setLoveCount(love);

            String commentCount = (String) redisTemplate.opsForHash().get("COMMENT_" + id.toHexString(), "COMMENT_COUNT");
            Integer comment;
            if (commentCount==null){
                comment= 0;
            }else {
                comment = Integer.valueOf(commentCount);
            }
            item.setCommentCount(comment);
        }
    }

    //朋友动态
    public PageResult findFriend(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();
        List<Movement> list = movementApi.findFriend(userId, page, pagesize);
        //查询hasLiked、hasLoved
        for (Movement vo : list) {

            Object o = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LIKE_" + userId);
            if (o==null){
                vo.setHasLiked(0);
            }else {
                vo.setHasLiked(1);
            }
            Object o1 = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LOVE_" + userId);
            if (o1==null){
                vo.setHasLoved(0);
            }else {
                vo.setHasLoved(1);
            }
        }

        if (CollUtil.isEmpty(list)) {
            return new PageResult();
        }
        //查询喜欢数、点赞数、评论数
        this.count(list);

        List<Long> ids = CollUtil.getFieldValues(list, "userId", Long.class);

        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);
        PageResult pageResult = getPageResult(page, pagesize, list, infoMap);
        return pageResult;
    }

    //抽取封装vo方法
    private PageResult getPageResult(Integer page, Integer pagesize, List<Movement> list, Map<Long, UserInfo> infoMap) {
        List<MovementsVo> movementsVoList = new ArrayList<>();
        for (Movement movement : list) {
            UserInfo userInfo = infoMap.get(movement.getUserId());

            if (userInfo != null) {
                MovementsVo vo = MovementsVo.init(userInfo, movement);
                movementsVoList.add(vo);
            }
        }
        return new PageResult(page, pagesize, 0l, movementsVoList);
    }

    //推荐动态
    public PageResult recommend(Integer page, Integer pagesize) {
        Long userId = UserHolder.getUserId();
        List<Long> ids = new ArrayList<>();
        String redisKey = Constants.MOVEMENTS_RECOMMEND + userId;
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        List<Movement> list = new ArrayList<>();
        if (StringUtils.isEmpty(redisValue)) {
            list = movementApi.randomRecommend(pagesize);
        } else {
            String[] split = redisValue.split(",");
            if ((page - 1) * pagesize < split.length) {
                List<Long> pids = Arrays.stream(split).skip((page - 1) * pagesize)
                        .limit(pagesize).map(o -> Long.valueOf(o)).collect(Collectors.toList());
                list = movementApi.findMovementsByPids(pids);
            }
        }
        this.count(list);
        //查询hasLiked、hasLoved
        for (Movement vo : list) {

            Object o = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LIKE_" + userId);
            if (o==null){
                vo.setHasLiked(0);
            }else {
                vo.setHasLiked(1);
            }
            Object o1 = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LOVE_" + userId);
            if (o1==null){
                vo.setHasLoved(0);
            }else {
                vo.setHasLoved(1);
            }
        }
        for (Movement movement : list) {
            ids.add(movement.getUserId());
        }
        Map<Long, UserInfo> infoMap = userInfoApi.findByIds(ids, null);
        PageResult pageResult = getPageResult(page, pagesize, list, infoMap);
        return pageResult;
    }

    //查一条动态
    public MovementsVo findOne(String id) {
        Long userId1 = UserHolder.getUserId();

        Movement movement = movementApi.findOne(id);
        if (movement != null) {
            Long userId = movement.getUserId();
            UserInfo userInfo = userInfoApi.findById(userId);
            MovementsVo vo = MovementsVo.init(userInfo, movement);
            //查询hasLiked、hasLoved
            Object o = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LIKE_" + userId1);
            if (o==null){
                vo.setHasLiked(0);
            }else {
                vo.setHasLiked(1);
            }
            Object o1 = redisTemplate.opsForHash().get("COMMENT_" + vo.getId(), "USER_LOVE_" + userId1);
            if (o1==null){
                vo.setHasLoved(0);
            }else {
                vo.setHasLoved(1);
            }
            ObjectId movementId = movement.getId();
            String likeCount = (String) redisTemplate.opsForHash().get("COMMENT_" + movementId.toHexString(), "LIKE_COUNT");
            Integer like;
            if (likeCount==null){
                like= 0;
            }else {
                like = Integer.valueOf(likeCount);
            }
            movement.setLikeCount(like);

            String loveCount = (String) redisTemplate.opsForHash().get("COMMENT_" + movementId.toHexString(), "LOVE_COUNT");
            Integer love;
            if (loveCount==null){
                love= 0;
            }else {
                love = Integer.valueOf(loveCount);
            }
            movement.setLoveCount(love);

            String commentCount = (String) redisTemplate.opsForHash().get("COMMENT_" + movementId.toHexString(), "COMMENT_COUNT");
            Integer comment;
            if (commentCount==null){
                comment= 0;
            }else {
                comment = Integer.valueOf(commentCount);
            }
            movement.setCommentCount(comment);

            return vo;
        } else {
            return null;
        }
    }

    //点赞
    public Integer commend(String id) {
        Long userId = UserHolder.getUserId();
        //存redis
        redisTemplate.opsForHash().put("COMMENT_" + id, "USER_LIKE_" + userId, "1");
        String likeCount = (String) redisTemplate.opsForHash().get("COMMENT_" + id, "LIKE_COUNT");
        if (likeCount != null) {
            Integer i = Integer.valueOf(likeCount) + 1;
            redisTemplate.opsForHash().put("COMMENT_" + id, "LIKE_COUNT", i.toString());
            return i;
        } else {
            redisTemplate.opsForHash().put("COMMENT_" + id, "LIKE_COUNT", "1");
            return 1;
        }
    }
    // 取消点赞
    public Integer uncommend(String id) {
        Long userId = UserHolder.getUserId();

        redisTemplate.opsForHash().delete("COMMENT_" + id, "USER_LIKE_" + userId, "1");
        String likeCount = (String) redisTemplate.opsForHash().get("COMMENT_" + id, "LIKE_COUNT");
        Integer i = Integer.valueOf(likeCount) - 1;
        redisTemplate.opsForHash().put("COMMENT_" + id, "LIKE_COUNT", i.toString());
        return i;
    }

    //喜欢动态
    public Integer love(String id) {
        Long userId = UserHolder.getUserId();

        redisTemplate.opsForHash().put("COMMENT_" + id, "USER_LOVE_" + userId, "1");
        String loveCount = (String) redisTemplate.opsForHash().get("COMMENT_" + id, "LOVE_COUNT");
        if (loveCount != null) {
            Integer i = Integer.valueOf(loveCount) + 1;
            redisTemplate.opsForHash().put("COMMENT_" + id, "LOVE_COUNT", i.toString());
            return i;
        } else {
            redisTemplate.opsForHash().put("COMMENT_" + id, "LOVE_COUNT", "1");
            return 1;
        }
    }

    //取消喜欢
    public Integer unlove(String id) {
        Long userId = UserHolder.getUserId();
        redisTemplate.opsForHash().delete("COMMENT_" + id, "USER_LOVE_" + userId, "1");
        String loveCount = (String) redisTemplate.opsForHash().get("COMMENT_" + id, "LOVE_COUNT");
        Integer i = Integer.valueOf(loveCount) - 1;
        redisTemplate.opsForHash().put("COMMENT_" + id, "LOVE_COUNT", i.toString());
        return i;
    }
}